# coding: utf-8
# 1 打开专辑页面
#   专辑页面分页显示的url：https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=65465072&pageNum=1&sort=0
#   返回的是json格式数据 其中包含当前页音频trackId，音源总数
# 2 传入音频id访问音频播放页面
#   列表中的url：https://www.ximalaya.com/sound/trackId 示例 https://www.ximalaya.com/sound/35393671
# 3 请求src的url 响应返回音频json数据解析出音频文件地址
#   请求包含音频源地址json格式数据的url：https://www.ximalaya.com/revision/play/v1/audio?id=trackId&ptype=1
#   示例：https://www.ximalaya.com/revision/play/v1/audio?id=35984516&ptype=1
#   返回包含音源url的json格式数据
#   url示例：https://aod.cos.tx.xmcdn.com/storages/209e-audiofreehighqps/B4/90/GKwRIasGNsnrAE2txgFAkZmk-aacv2-48K.m4a
# 4 下载m4a音频文件

import requests,re,json

ROOT_PATH = 'C:/E/temp/pic/'
HEADER = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    #,"sec-ch-ua": 'Google Chrome";v="87", " Not;A Brand";v="99", "Chromium";v="87'
    #,"Referer": "https://www.ixigua.com"
}
#辅助工具一：把字符串文本保存到文件
def printHtmlToTempFile(txt:str,filename:str):
    with open(ROOT_PATH+filename,'w',encoding='utf-8') as f:
        f.write(txt)
#辅助工具二：从文件中读取文本
def getHtmlFromFile(filename:str):
    with open(ROOT_PATH+filename,'r',encoding='utf-8') as r:
        return r.read()
#获取页面的html
def getPageHtml(url:str):
    _response = requests.get(url,headers=HEADER)
    return _response.text 

#从专辑页面的html文本中获取访问音频页面的url集合
LIST_AUDIO_PATTERN = '<li class="b_t"><div class="text b_t"><a href="(.*?)"><span class="title b_t">(.*?)</span></a></div><div class="right b_t"><div class="operate b_t"><span class="count b_t"><i class="xuicon xuicon-erji1 b_t"></i>.*?</span></div><span class="time b_t">.*?</span></div></li>'
audio_dict = {} 
def getAlbumListFromHtml(html:str):
    _list = re.findall(LIST_AUDIO_PATTERN,html)
    for audio in _list:
        _url = audio[0]
        _audio_id = _url.split(r'/')[-1]
        _name = audio[1]
        audio_dict[_audio_id] = _name

#访问单个音频页面url会返回json格式数据，解析出音频源地址
#列表中的url：//www.ximalaya.com/sound/35393671
#请求包含音频源地址json格式数据的url：https://www.ximalaya.com/revision/play/v1/audio?id=35984516&ptype=1
def getAudioSourceUrl(audioPageUrl:str):
    json_txt = getPageHtml(audioPageUrl)
    audio_info = json.loads(json_txt)
    if audio_info['data']['src'] :
        return audio_info['data']['src']
    else :
        return ''

#下载音频文件
def downloadAudio(url:str,file_name:str):
    if not re.match('^http[s]{0,1}://',url):
        return
    if requests.head(url).status_code != 200:
        return
    _response = requests.get(url,headers=HEADER,stream=True)
    #_content = _response.content
    _content_size = int(_response.headers.get('content-length'))
    _data_count = 0
    with open(file_name,'ab') as _f :
        for chunk in _response.iter_content(chunk_size=40960):
            if chunk :
                _f.write(chunk)
                _data_count += len(chunk)
                _now_rate = (_data_count/_content_size)*100
                print('\rloading...: %02d%% (%d/%d)' % (_now_rate,_data_count,_content_size),end=' ')
    _response.close() #stream=True时必须要手动关闭response
NO_SIZE = 5
def nameImg(index:int,size=NO_SIZE):
    index_str = str(index)
    index_size = len(index_str)
    divide = size-index_size
    if divide > 0:
        return '0'*divide+index_str
    else :
        return index_str
def mainProcess(_id:str):
    audio_dict = {}
    pageUrl = 'https://www.ximalaya.com/album/'+str(_id)
    albumId = pageUrl.split(r'/')[-1]
    albumListUrlPattern = 'https://www.ximalaya.com/revision/album/v1/getTracksList?albumId={param_albumId}&pageNum={pageNum}&sort=0'#sort=0按正序排列
    index = 1
    while True:
        url = albumListUrlPattern.format(param_albumId=albumId,pageNum=index)
        #print(url)
        info_json = json.loads(requests.get(url,headers=HEADER).text)
        tracks = info_json['data']['tracks']
        if len(tracks) < 1 :
            break
        for track in tracks:
            audio_dict[str(track['trackId'])] = track['title']
        index += 1
    print(len(audio_dict))
    audioPageUrlPattern = 'https://www.ximalaya.com/revision/play/v1/audio?id={trackId}&ptype=1'
    for _trackId,_title in audio_dict.items():
        trackUrl = getAudioSourceUrl(audioPageUrlPattern.format(trackId=_trackId))
        print(_title,trackUrl)
        downloadAudio(trackUrl,ROOT_PATH+_title+r'.mp3')


import sys
if __name__ == '__main__':
    mainProcess(sys.argv[1])

